home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / dxcmds34.sit / Dartmouth XCMD's 3.4.3 / card_4672.txt < prev    next >
Text File  |  1990-04-17  |  16KB  |  466 lines

  1. -- card: 4672 from stack: in.3
  2. -- bmap block id: 0
  3. -- flags: 4000
  4. -- background id: 3241
  5. -- name: FileToField
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XCMD,FileToField,it
  10. end Install
  11.  
  12.  
  13. -- part 1 (button)
  14. -- low flags: 00
  15. -- high flags: A003
  16. -- rect: left=79 top=300 right=322 bottom=179
  17. -- title width / last selected line: 0
  18. -- icon id / first selected line: 0 / 0
  19. -- text alignment: 1
  20. -- font id: 0
  21. -- text size: 12
  22. -- style flags: 0
  23. -- line height: 16
  24. -- part name: FileToField
  25. ----- HyperTalk script -----
  26. on mouseUp
  27.   FileToField "card field 1"
  28.   get the result
  29.   if it is not empty then put it
  30.   if "Cancel" is not in it and "Error" is not in it then
  31.     show card field 1
  32.     set the visible of card button 2 to true
  33.   end if
  34. end mouseUp
  35.  
  36.  
  37.  
  38. -- part 2 (field)
  39. -- low flags: 81
  40. -- high flags: 2007
  41. -- rect: left=265 top=33 right=296 bottom=486
  42. -- title width / last selected line: 0
  43. -- icon id / first selected line: 0 / 0
  44. -- text alignment: 0
  45. -- font id: 20
  46. -- text size: 12
  47. -- style flags: 0
  48. -- line height: 16
  49. -- part name: FileToField Text
  50.  
  51.  
  52. -- part 3 (button)
  53. -- low flags: 80
  54. -- high flags: A003
  55. -- rect: left=284 top=268 right=290 bottom=458
  56. -- title width / last selected line: 0
  57. -- icon id / first selected line: 0 / 0
  58. -- text alignment: 1
  59. -- font id: 0
  60. -- text size: 12
  61. -- style flags: 0
  62. -- line height: 16
  63. -- part name: Empty and Hide this Field
  64. ----- HyperTalk script -----
  65. on mouseUp
  66.   set lockscreen to true
  67.   put empty into card field 1
  68.   hide card field 1
  69.   set the visible of me to false
  70.   -- doMenu "Compact Stack"
  71.   set lockscreen to false
  72. end mouseUp
  73.  
  74.  
  75.  
  76. -- part 6 (field)
  77. -- low flags: 81
  78. -- high flags: 2007
  79. -- rect: left=12 top=26 right=298 bottom=491
  80. -- title width / last selected line: 0
  81. -- icon id / first selected line: 0 / 0
  82. -- text alignment: 0
  83. -- font id: 22
  84. -- text size: 10
  85. -- style flags: 0
  86. -- line height: 13
  87. -- part name: Source
  88.  
  89.  
  90. -- part 8 (button)
  91. -- low flags: 00
  92. -- high flags: A003
  93. -- rect: left=299 top=300 right=322 bottom=438
  94. -- title width / last selected line: 0
  95. -- icon id / first selected line: 0 / 0
  96. -- text alignment: 1
  97. -- font id: 0
  98. -- text size: 12
  99. -- style flags: 0
  100. -- line height: 16
  101. -- part name: Show Pascal Source
  102. ----- HyperTalk script -----
  103. on mouseUp
  104.   set the visible of card field 2 to not the visible of card field 2
  105.   if the visible of card field 2 is true then
  106.     set the name of me to "Hide Pascal Source"
  107.   else set the name of me to "Show Pascal Source"
  108. end mouseUp
  109.  
  110.  
  111.  
  112. -- part contents for background part 16
  113. ----- text -----
  114. FILETOFIELD XCMD version 1.5
  115. Kevin Calhoun
  116.  
  117. The FileToField XCMD copies the contents of a text file into a HyperCard field.  You may choose the text file to copy from by selecting it from a standard file dialog box or by specifying its full pathname.
  118.  
  119. If the text file is too large (just under 30K is the practical limit for HyperCard fields), FileToField won't try to copy it into the field.  If this or any other error occurs, FileToField will return an error message as the result.  Word 1 of this message will be "Error".  If the text was copied successfully, FileToField returns the full pathname of the file as the result.
  120.  
  121. INVOKING FILETOFIELD
  122.  
  123. FileToField "fieldDesignation",<"full pathname of file">
  124.  
  125. You may designate the field into which the text is to be copied in any way considered valid by HyperCard, by number, id, or name, with one exception:  you can't use the field's name if it is more than one word.  If you do use the field's name, don't put the field name in quotation marks.  Nested quotations confuse HyperCard.  (See the examples below.)
  126.  
  127. If you don't supply the pathname of the file to be copied from, FileToField will invoke SFGetFile, and the user can select the file from the dialog box.  If the user pushes the cancel button of the dialog box, FileToField returns "Cancel" as the Result.
  128.  
  129. examples--
  130.  
  131. FileToField("card field 1")                --these examples copy files chosen from the
  132. FileToField("bkgnd field id 16")       --standard file dialog into the specified field
  133. FileToField("card field Memorex")
  134.  
  135. FileToField "field 5","OldAchesAndPains:Good Stuff:Secrets"  --this copies the file 
  136. "Secrets" into background field 5.
  137.  
  138. REVISION HISTORY
  139. 7 March 1988: release of version 1.0
  140. 31 March 1988: release of version 1.1
  141.   --better reporting of memory errors
  142.   --more compact code
  143. 16 May 1988: release of version 1.2
  144.   -- fixed bug that bombed Mac Plus (switched from PBHOpen to FSOpen)
  145. 15 March 1989 -- 1.5
  146.   -- Altered source code for compatibility with MPW Pascal 3.0.
  147.  
  148. -- part contents for card part 6
  149. ----- text -----
  150. UNIT FileToFieldUnit;
  151.  
  152. { FileToField XCMD ┬⌐ 1988-1989 by the Trustees of Dartmouth College }
  153. { Written by Kevin Calhoun }
  154.  
  155. { This source compatible with MPW Pascal 3.0 }
  156.  
  157. (*
  158. Pascal FileToField.p
  159. Link -m ENTRYPOINT Γêé
  160.      -o "YourFile" Γêé
  161.      -rt XCMD=2235 Γêé
  162.      -sn Main=FileToField Γêé
  163.      FileToField.p.o Γêé
  164.     "{Libraries}"interface.o Γêé
  165.     "{PLibraries}"Paslib.o Γêé
  166.     "{Libraries}"HyperXLib.o
  167. *)
  168.  
  169. {$R-}
  170.  
  171. INTERFACE
  172.   USES
  173.     Types,
  174.     Memory,
  175.     Files,
  176.     Resources,
  177.     Packages,
  178.     HyperXCmd;
  179.  
  180.   PROCEDURE EntryPoint (paramPtr : XCmdPtr);
  181.  
  182. IMPLEMENTATION
  183.  
  184.   PROCEDURE FileToField(paramPtr : XCmdPtr); FORWARD;
  185.  
  186.   PROCEDURE EntryPoint(paramPtr : XCmdPtr);
  187.   BEGIN
  188.     FileToField(paramPtr);
  189.   END;
  190.  
  191.   FUNCTION GetScreenBitsBounds: Rect;
  192.   { get screenbits.bounds from the QuickDraw globals }
  193.   TYPE
  194.     LongwordPtr = ^LONGINT;
  195.     BitMapPtr = ^BitMap;
  196.   CONST
  197.     screenBitsOffset = -122;
  198.     CurrentA5 = $904;
  199.   VAR
  200.     screenBitsPtr : BitMapPtr;
  201.     myLongwordPtr : LongwordPtr;
  202.   BEGIN
  203.     myLongwordPtr := LongwordPtr(CurrentA5);
  204.       { myLongwordPtr now points to the pointer to the first QD global }
  205.     myLongwordPtr := LongwordPtr(myLongwordPtr^);
  206.       { myLongwordPtr now points to the first QD global }
  207.     screenBitsPtr := BitMapPtr(myLongwordPtr^ + screenBitsOffset);
  208.       { screenBitsPtr now points to the screenBits BitMap }
  209.     GetScreenBitsBounds := screenBitsPtr^.bounds;
  210.   END;
  211.  
  212.   FUNCTION BuildThePathname (fName : Str255;
  213.                   vRefNum : INTEGER) : Str255;
  214. { Given the "short name" and vRefNum of a file, returns the full pathname. }
  215. { This function is adapted from Steve Maller's FileName XFCN published in }
  216. { HyperTalk Programming by Dan Shafer, Howard W. Sams & Company, 1988, }
  217. { pp. 399-403. }
  218.     VAR
  219.       name, fullPathName : Str255;
  220.       err : INTEGER;
  221.       myWDPB : WDPBPtr;
  222.       myCPB : CInfoPBPtr;
  223.       myPB : HParmBlkPtr;
  224.  
  225.   BEGIN
  226.     fullPathName := '';     { start with an empty pathname }
  227. { Allocate some memory in the heap for the parameter block. }
  228.     myCPB := CInfoPBPtr(NewPtr(SizeOf(HParamBlockRec)));
  229.     IF ord4(myCPB) > 0 THEN    { continue if mem allocation was OK }
  230.  
  231.       BEGIN
  232.         myWDPB := WDPBPtr(myCPB);
  233.         myPB := HParmBlkPtr(myCPB);
  234. { same pointer, different variations of the record -- see IM IV, p. 117 }
  235.         name := '';     { start with an empty name for the volume }
  236.  
  237.         WITH myPB^ DO
  238.           BEGIN
  239.             ioNamePtr := @name;   { we want the volume name }
  240.             ioCompletion := pointer(0);
  241.             ioVRefNum := vRefNum;  { returned by SFGetFile }
  242.             ioVolIndex := 0;  { use the vRefNum and name only to designate volume }
  243.           END;
  244.         err := PBHGetVInfo(myPB, FALSE);  { fill in the volume info }
  245.         IF err = noErr THEN
  246.  
  247.           BEGIN
  248. { Now we need the Working Directory (WD) information because we're }
  249. { going to step backwards from the file through all of the folders until }
  250. { we reach the root directory. }
  251.             WITH myWDPB^ DO
  252.               BEGIN
  253.                 ioVRefNum := vRefNum;  { this got set to 0 above }
  254.                 ioWDProcID := 0;   { use the vRefNum }
  255.                 ioWDIndex := 0;     { we want all directories }
  256.               END;
  257.             err := PBGetWDInfo(myWDPB, FALSE);
  258.             IF err = noErr THEN
  259.               BEGIN
  260.                 WITH myCPB^ DO
  261.                   BEGIN
  262.                     ioFDirIndex := -1;   { use the ioDirID field only }
  263.                     ioDrDirID := myWDPB^.ioWDDirID;   { info returned above }
  264.                   END;
  265.                 err := PBGetCatInfo(myCPB, FALSE);
  266.                 IF err = noErr THEN
  267.                   BEGIN
  268.  
  269. { Here starts the real work -- start to climb the tree by continually }
  270. { looking in the ioDrParID field for the next directory above until we fail... }
  271.                     myCPB^.ioDrDirID := myCPB^.ioDrParID;  { the first folder }
  272.                     fullPathName := CONCAT(myCPB^.ioNamePtr^, ':', fName);
  273.                     REPEAT
  274.                       myCPB^.ioDrDirID := myCPB^.ioDrParId;
  275.                       err := PBGetCatInfo(myCPB, FALSE);    { the next level }
  276. { Be careful of an error returned here -- it means the user chose a file on the }
  277. { desktop level of this volume.  If this is the case, just stop here and return }
  278. { "VolumeName:FileName"; otherwise loop until failure. }
  279.                       IF err = noErr THEN
  280.                         fullPathName := CONCAT(myCPB^.ioNamePtr^, ':', fullPathName);
  281.                     UNTIL err <> noErr;
  282.                   END;  { if PBGetCatInfo worked OK }
  283.               END;  { if PBGetWDInfo worked OK }
  284.           END;  { if PBHGetVInfo worked OK }
  285.         DisposPtr(pointer(myCPB));
  286.       END;  { if we had enough room for a new pointer }
  287.     BuildThePathname := fullPathName;
  288.   END;
  289.  
  290.   PROCEDURE PassReturnValue (paramPtr : XCMDPtr;
  291.                   theMsg : Str255); { set theResult }
  292.   BEGIN
  293.     paramPtr^.returnValue := PasToZero(paramPtr, theMsg);
  294.   END;
  295.  
  296.   PROCEDURE SetField (paramPtr : XCmdPtr;
  297.                   theStringPtr : Ptr;
  298.                   theTextHandle : handle);
  299.     VAR
  300.       whichField, theString : Str255;
  301.       cardFieldFlag : BOOLEAN;
  302.       matchPtr : Ptr;
  303.       theResult : Handle;
  304.       fieldID : INTEGER;
  305.  
  306.   BEGIN
  307. { get Pascal string that contains designation of field to be printed }
  308.     ZeroToPas(paramPtr, theStringPtr, whichField);
  309. { get long name of this field to see if it's a card or bkgnd field }
  310.     theResult := EvalExpr(paramPtr, CONCAT('the long name of ', whichField));
  311.     IF (paramPtr^.result = noErr) THEN
  312.       BEGIN
  313.         MoveHHi(theResult);
  314.         HLock(theResult);
  315.  
  316. { see if this thing actually is an extant field }
  317. { if HC returns a long field name with the word 'card' in it, we'll assume it's real }
  318.         matchPtr := StringMatch(paramPtr, 'card', theResult^);
  319.  
  320.         IF (matchPtr <> NIL) AND (paramPtr^.result = noErr) THEN  { this must be a field after all }
  321.           BEGIN
  322. { check to see if name of field contains 'card field' -- so we can set the cardFieldFlag }
  323.             matchPtr := StringMatch(paramPtr, 'card field', theResult^);
  324.             cardFieldFlag := (matchPtr <> NIL);
  325. { free the space allocated by EvalExpr above }
  326.             DisposHandle(theResult);
  327.  
  328. { get the id of this field }
  329.             theResult := EvalExpr(paramPtr, CONCAT('the id of ', whichField));
  330.             IF (theResult <> NIL) AND (paramPtr^.result = noErr) THEN
  331.               BEGIN
  332.                 MoveHHi(theResult);
  333.                 HLock(theResult);
  334. { convert it into a string, then into a number }
  335.                 ZeroToPas(paramPtr, theResult^, theString);
  336.                 fieldID := StrToNum(paramPtr, theString);
  337.                 DisposHandle(theResult);  { and free the memory allocated by EvalExpr }
  338.  
  339.                 SetFieldByID(paramPtr, cardFieldFlag, fieldID, theTextHandle);
  340.               END;
  341. { set the contents of the field to the contents of theTextHandle }
  342.           END;
  343.       END;
  344.     IF GetHandleSize(theResult) <> 0 THEN DisposHandle(theResult);
  345.   END;
  346.  
  347.   PROCEDURE FileToField (paramPtr : XCmdPtr);
  348.     VAR
  349.       reply : SFReply;   { returned by SFGetFile }
  350.       fileName : Str255;  { name of file to open }
  351.       theVRefNum : INTEGER;  { ref num of volume (or directory) on which the file resides }
  352.       theRefNum : INTEGER;  { refNum of file, for file manager calls }
  353.       err : OSErr;  { save error codes for reporting trouble }
  354.       logEOF : longint;   { length of file }
  355.       theBufHndl : Handle;  { for copying contents of file into memory }
  356.       zeroPtr: Ptr;
  357.       parameterCount : INTEGER;  { the number of parameters passed to us }
  358.       didSFGet : BOOLEAN;
  359.       numStr : Str255;
  360.  
  361.     PROCEDURE DoSFGet;
  362.       VAR
  363.         where : point;
  364.         typeList : SFTypeList;
  365.         dlgt: DialogTHndl;
  366.         r: rect;
  367.         screen: rect;
  368.         h, v: INTEGER;
  369.     BEGIN  { select text file to read using SFGetFile }
  370.       dlgt := DialogTHndl(GetResource('DLOG',getDlgID));
  371.       if dlgt <> nil then
  372.         begin
  373.         r := dlgt^^.boundsRect;
  374.         screen := GetScreenBitsBounds;
  375.         h := ((screen.right - screen.left) - (r.right - r.left)) div 2;
  376.         v := ((screen.bottom - screen.top) - (r.bottom - r.top)) div 2;
  377.         SetPt(where, h, v);
  378.         end
  379.       else SetPt(where, 82, 75);
  380.       typeList[0] := 'TEXT';  { tell SFGetFile to display only text files }
  381.       SFGetFile(where, '', NIL, 1, typeList, NIL, reply);
  382.     END;
  383.  
  384.     FUNCTION GetFileName : Str255;
  385.            { return the name of the file to copy from }
  386.       VAR
  387.         temp : Str255;
  388.     BEGIN
  389.       IF parameterCount > 1 THEN
  390.         BEGIN
  391.           ZeroToPas(paramPtr, paramPtr^.params[2]^, temp);
  392.           didSFGet := FALSE;
  393.         END
  394.       ELSE
  395.         BEGIN
  396.           doSFGet;
  397.           IF reply.good = TRUE THEN temp := reply.fName
  398.           ELSE temp := '';
  399.           didSFGet := TRUE;
  400.         END;
  401.       GetFileName := temp;
  402.     END;
  403.  
  404.   BEGIN
  405.     parameterCount := paramPtr^.paramCount;
  406.     IF parameterCount > 0 THEN
  407.       BEGIN
  408.         fileName := GetFileName;
  409.         IF fileName <> '' THEN
  410.           BEGIN
  411.             IF didSFGet THEN theVRefNum := reply.vRefNum
  412.             ELSE theVRefNum := 0;
  413.             err := FSOpen(fileName, theVRefNum, theRefNum);
  414.             IF err = noErr THEN
  415.               BEGIN
  416.                 err := GetEOF(theRefNum, logEOF);
  417.                 IF err = noErr THEN
  418.                   IF logEOF < 29990 THEN
  419. { 29990 bytes is my experimental value for the maximum safe size of HC fields }
  420.                     BEGIN
  421.                       theBufHndl := NewHandle(logEOF);
  422.                       err := MemError;
  423.                       IF (theBufHndl <> NIL) AND (err = noErr) THEN
  424.                         BEGIN
  425.                           MoveHHi(theBufHndl);
  426.                           HLock(theBufHndl);
  427.                           err := FSRead(theRefNum, logEOF, theBufHndl^);
  428.                           IF err = noErr THEN
  429.                             BEGIN
  430.                               HUnlock(theBufHndl);
  431.                               SetHandleSize(theBufHndl,logEOF+1);
  432.                               zeroPtr := Ptr(ORD4(theBufHndl^)+logEOF);
  433.                               zeroPtr^ := 0;
  434.                               IF err = noErr THEN
  435.                                 BEGIN
  436.                                   SetField(paramPtr, paramPtr^.params[1]^, theBufHndl);
  437.                                   IF didSFGet THEN
  438.                                     fileName := BuildThePathname(fileName, theVRefNum);
  439.                                   PassReturnValue(paramPtr, fileName);
  440.                                 END;
  441.                             END;
  442.                           DisposHandle(theBufHndl);
  443.                         END   { if theBufHndl <> nil }
  444.                       ELSE
  445.                         BEGIN
  446.                         NumToStr(paramPtr, err,numStr);
  447.                         PassReturnValue(paramPtr, CONCAT('Error ', numStr));
  448.                         END;
  449.                     END        { if the file wasn't too big to read in }
  450.                   ELSE PassReturnValue(paramPtr, 'Error (file too big)');
  451.                 err := FSClose(theRefNum);
  452.               END;   { if err = noErr in opening the file }
  453.             IF err <> noErr THEN   { if we had an error, report it }
  454.               BEGIN
  455.               NumToStr(paramPtr, err,numStr);
  456.               PassReturnValue(ParamPtr, CONCAT('Error ', numStr));
  457.               END;
  458.           END
  459.         ELSE PassReturnValue(paramPtr, 'Cancel');
  460.       END  { if we got parameters }
  461.     ELSE
  462.       PassReturnValue(paramPtr, 'FileToField XCMD 1.5, 15 March 1989, ┬⌐1988-1989 Dartmouth College');
  463.   END;
  464.  
  465.  
  466. END.